﻿using System.Collections.ObjectModel;
using System.IO;
using System.Reflection;
using System.Xml.XPath;
using DbSetupHelper.Common;
using DbSetupHelper.Common.Exceptions;
using DbSetupHelper.Plugin.ScriptPackage;
using System;

namespace DbSetupHelper.Business
{
    /// <summary>
    /// Object used to seperate out the XML parser.
    /// </summary>
    static class XmlParser
    {
        /// <summary>
        /// Generates the run parms object from the control xml.
        /// </summary>
        /// <param name="scriptPackage">The script package object.</param>
        /// <returns></returns>
        public static RunParameters GenerateRunParms(IScriptPackage scriptPackage)
        {
            //TODO: When removing the GenerateRunParms(XPathNavigator) move the code to this method.
            XPathNavigator xmlNavigator = new XPathDocument(scriptPackage.FetchControlXmlStream()).CreateNavigator();
            bool throwError = true;
            RunParameters runParms = new RunParameters();
            xmlNavigator.MoveToRoot();

            while (xmlNavigator.MoveToFirstChild() == true && xmlNavigator.Name != "Defaults")
            { ;}

            if (xmlNavigator.Name == "Defaults")
            {
                throwError = false;
                xmlNavigator.MoveToFirstChild();
                do
                {
                    switch (xmlNavigator.Name)
                    {
                        case "UserName":
                            runParms.UserName = xmlNavigator.Value;
                            break;
                        case "Password":
                            runParms.Password = xmlNavigator.Value;
                            break;
                        case "Server":
                            runParms.SqlServer = xmlNavigator.Value;
                            break;
                        case "DatabaseName":
                            runParms.DatabaseName = xmlNavigator.Value;
                            break;
                        case "DbUserName":
                            runParms.DbUserName = xmlNavigator.Value;
                            break;
                        case "DbPassword":
                            runParms.DbPassword = xmlNavigator.Value;
                            break;
                    }
                }
                while (xmlNavigator.MoveToNext());
            }

            if (throwError)
                throw new MalformedControlXmlException();

            return runParms;
        }

        /// <summary>
        /// Generates the script pattern object from the control xml.
        /// </summary>
        /// <param name="scriptPackage">The script package object.</param>
        /// <returns></returns>
        public static Collection<DBScript> GenerateScriptPattern(IScriptPackage scriptPackage)
        {
            XPathNavigator xmlNavigator = new XPathDocument(scriptPackage.FetchControlXmlStream()).CreateNavigator();
            bool throwError = true;
            Collection<DBScript> scriptPattern = new Collection<DBScript>();
            RunParameters runParms = GenerateRunParms(scriptPackage);

            xmlNavigator.MoveToRoot();

            while (xmlNavigator.MoveToFirstChild() == true && xmlNavigator.Name != "Defaults")
            { ;}

            if (xmlNavigator.MoveToNext() && xmlNavigator.Name == "Scripts")
            {
                throwError = false;

                xmlNavigator.MoveToFirstChild(); //on script
                do
                {
                    string fileName;
                    bool disabled;
                    bool testInstall;
                    StreamReader reader;

                    xmlNavigator.MoveToFirstChild(); //on FileName
                    fileName = xmlNavigator.Value;
                    xmlNavigator.MoveToNext(); //on Disabled
                    disabled = bool.Parse(xmlNavigator.Value);
                    xmlNavigator.MoveToNext(); //on TestInstallOnly
                    testInstall = bool.Parse(xmlNavigator.Value);
                    xmlNavigator.MoveToParent();

                    reader = new StreamReader(scriptPackage.FetchSqlScript(fileName));

                    DBScript dbScript = new DBScript(fileName, testInstall, disabled, reader.ReadToEnd());
                    dbScript.SetDefaultDatabaseName(runParms.DatabaseName);
                    dbScript.SetDefaultDatabaseUserName(runParms.DbUserName);
                    dbScript.SetDefaultDatabaseUserPassword(runParms.DbPassword);
                    scriptPattern.Add(dbScript);

                    reader.Dispose();
                }
                while (xmlNavigator.MoveToNext());
            }

            if (throwError)
                throw new MalformedControlXmlException();

            return scriptPattern;
        }
    }
}
